<?php
namespace Tbf\Bundle\DatabaseBundle\ThinkPhpModel;
use Tbf\Util\ArrayUtil;
class SchemaModel
{
    /**
     * @var Tpdo
     */
    protected $db;
    public function __construct(Tpdo $tpdo)
    {
        $this->db = $tpdo;
    }
    public function truncateTable($table_name)
    {
        $table_name = $this->db->quoteTableName($table_name);
        $sql = 'truncate table '.$table_name;
        $this->db->query($sql);
    }
    public function dropTable($table_name,$error_on_not_exist = false)
    {
        $table_name = $this->db->quoteTableName($table_name);
        if ($error_on_not_exist) {
            $sql = 'drop table '.$table_name;
        } else {
            $sql = 'drop table if exists '.$table_name;
        }
        $this->db->query($sql);
    }
    public function getPkName($table_name)
    {
        $describe = $this->describe($table_name);
        foreach ($describe as $name=>$field) {
            if ($field['key']=='PRI') {
                return $name;
            }
        }

        return false;
    }
    public function describe($table_name)
    {
        $quote_table_name = $this->db->quoteTableName($table_name);
        $ret = $this->db->query('describe '.$quote_table_name);
        $output = array();
        foreach ($ret as $field) {
            $field = ArrayUtil::keyToLower($field);
            $output[$field['field']] = $field;
        }

        return $output;
    }
    public function showTable($dbname = '')
    {
        $ret = $this->db->query('show tables');
        $output = array();
        foreach ($ret as $v1) {
            $table_name = array_pop($v1);
            $output[] = $table_name;
        }

        return $output;
    }
    public function copyTable($src_origin,$to_origin,$config = array())
    {
        $to = $this->db->quoteTableName($to_origin);
        $src = $this->db->quoteTableName($src_origin);
        $this->copyTableSchema($src_origin,$to_origin,$config);
        $this->db->query('insert into '.$to.' select * from '.$src);
    }
    public function copyTableSchema($src_origin,$to_origin,$config=array())
    {
        $to = $this->db->quoteTableName($to_origin);
        $src = $this->db->quoteTableName($src_origin);
        $default = array(
            'overwrite'=>false
        );
        $config = array_merge($default,$config);
        if ($config['overwrite']) {
            $this->db->query('drop table if exists '.$to);
        }
        $sql = 'create table '.$to.' like '.$src;
        $this->db->query($sql);
    }
    /**
    * 尽力把表转换为内存表
    * text和blob转成varchar
    */
    public function alterTableToMemory($origin_table_name,$config=array())
    {
        $default_config = array(
            'db_error'=>'ignore' //exception ignore
        );
        $config = array_merge($default_config,$config);
        $table_name = $this->db->quoteTableName($origin_table_name);
        try {
            $this->db->query('alter table '.$table_name.'engine=memory');

            return true;
        } catch (\PDOException $e) {
            if ($config['db_error']=='exception') {
                throw $e;
            }
        }
        //text和blob转成varchar
        $describe = $this->describe($origin_table_name);
        $toAlter = array();
        foreach ($describe as $name=>$field) {
            $type = $field['type'];
            if ($type=='text'||$type=='blob') {
                $toAlter[] = 'change '.$name.' '.$name.' varchar(255)';
            }
        }
        $this->db->query('alter table '.$table_name.' '.implode(',',$toAlter));
        $this->db->query('alter table '.$table_name.'engine=memory');

        return true;
    }
}
